/*
 ------------------------------------------------------------------------------
 Copyright (C) 2009-2011 Eternal Games.

 This file is part of the Eternal Tech source code.

 The Eternal Tech source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Eternal Tech source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Eternal Tech source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// g_character.cpp - ...
//

#include "g_local2.h"

uint64 ipow(uint64 a, uint64 ex)
// Return a**ex
{
    if ( 0==ex )  return 1;
    else
    {
        uint64 z = a;
        uint64 y = 1;
        while ( 1 )
        {
            if ( ex & 1 )  y *= z;
            ex /= 2;
            if ( 0==ex )  break;
            z *= z;
        }
        return y;
    }
}

void Character_Init(CharacterData *character, edict_t *player)
{
	character->Player = player;
	character->Level = 1;
	character->Experience = 0;
	character->NextLevelExperience = Character_CalculateExperienceForLevel(character, character->Level + 1);
	character->Party = NULL;

	CheckPartilessPlayer(character);
	Targetables_Add(player);
}

void Character_Destroy(CharacterData *character)
{
	RemovePlayerFromParty(character);
	Targetables_Remove(character->Player);
}

uint64 Character_CalculateExperienceForLevel(CharacterData *character, uint8 level)
{
	return 250 * (level * level);
}

bool Character_SetExperience(CharacterData *character, uint64 wantedExperience)
{
	if (character->NextLevelExperience > wantedExperience)
	{
		character->Experience = wantedExperience;
		return false;
	}

	character->Experience = wantedExperience;
		
	character->Level++;
		
	character->NextLevelExperience = Character_CalculateExperienceForLevel(character, character->Level + 1);
	return true;
}

bool Character_IncreaseExperience(CharacterData *character, uint64 addedExperience)
{
	return Character_SetExperience(character, character->Experience + addedExperience);
}

void Character_SetLevel(CharacterData *character, uint8 newLevel)
{
	Character_SetExperience(character, Character_CalculateExperienceForLevel(character, newLevel));
}

byte Characters_GetAverageLevel()
{
	float level = 0;
	int count = 0;

	for (edict_t *player = &g_edicts[1]; player <= &g_edicts[1 + game.maxclients - 1]; ++player)
	{
		if (!player->client->pers.connected)
			continue;

		level += player->Character.Level;
		count++;
	}

	return (byte)(level / count);
}